import * as THREE from 'three';
import { BufferGeometry, Color, Geometry } from 'three';
import BaseThreeApp from '../BaseThreeApp';
import DebugInfo from '../DebugInfo';
// import img from '../images/bg.jpg';

const viewWidth = 7;
class _5_01Texture extends BaseThreeApp {
  public scene: THREE.Scene;
  public camera: THREE.OrthographicCamera;
  public renderer: THREE.WebGLRenderer;
  public texs: THREE.Texture[] = [];
  public mats: THREE.Material[] = [];
  public geos: (Geometry | BufferGeometry)[] = [];

  start() {
    this.scene = new THREE.Scene();
    const aspect = this.clientHeight / this.clientWidth;
    this.camera = new THREE.OrthographicCamera(
      -viewWidth,
      viewWidth,
      viewWidth * aspect,
      -viewWidth * aspect
    );
    this.camera.position.z = 9;

    this.renderer = new THREE.WebGLRenderer({
      canvas: this.element,
      antialias: true,
    });

    this.renderer.setDrawingBufferSize(this.clientWidth, this.clientHeight, 1);

    //左上角正方形
    const texLoader = new THREE.TextureLoader();
    const tex = texLoader.load('./images/bg.jpg');
    this.texs.push(tex);
    tex.repeat.set(2, 3.3);
    tex.wrapS = THREE.RepeatWrapping;
    tex.wrapT = THREE.RepeatWrapping;

    const squareGeo = new THREE.PlaneGeometry(3, 3);
    this.geos.push(squareGeo);
    const texMaterial = new THREE.MeshBasicMaterial({ map: tex });
    this.mats.push(texMaterial);
    const square = new THREE.Mesh(squareGeo, texMaterial);
    square.position.set(-3, 2, 0);
    this.scene.add(square);

    //左下角正方形
    const tex2 = texLoader.load('./images/bg.jpg');
    this.texs.push(tex2);
    tex2.repeat.set(1, 1.2);
    tex2.offset.set(0.2, 0.3);
    tex2.wrapS = THREE.RepeatWrapping;
    tex2.wrapT = THREE.RepeatWrapping;

    const texMaterial2 = new THREE.MeshBasicMaterial({ map: tex2 });
    this.mats.push(texMaterial2);
    const square2 = new THREE.Mesh(squareGeo, texMaterial2);
    square2.position.set(-3, -2, 0);
    this.scene.add(square2);

    //中间的正方形
    const tex3 = texLoader.load('./images/bg.jpg');
    tex3.wrapS = THREE.RepeatWrapping;
    tex3.wrapT = THREE.RepeatWrapping;
    tex3.dispose();

    this.texs.push(tex3);
    const geometry = new THREE.BoxGeometry(1, 1, 1);
    this.geos.push(geometry);
    const material = new THREE.MeshLambertMaterial({
      color: 0x00ffff,
      map: tex3,
    });
    const cube = new THREE.Mesh(geometry, material);
    this.scene.add(cube);

    //右上角正方形
    const geoBuff = new THREE.PlaneBufferGeometry(3, 3);
    const array = geoBuff.getAttribute('uv').array; //获取原本的纹理坐标
    console.log('Plane UV:' + array);
    const newUV: number[] = [];
    for (let i = 0; i < array.length / 2; i++) {
      newUV.push(array[i * 2 + 0]);
      newUV.push(array[i * 2 + 1] * 2); //纹理坐标的Y轴放大 *2。
    }
    geoBuff.setAttribute(
      'uv',
      new THREE.BufferAttribute(new Float32Array(newUV), 2)
    ); //重新设置纹理坐标

    this.geos.push(geoBuff);
    const texMaterial3 = new THREE.MeshBasicMaterial({ map: tex3 });
    this.mats.push(texMaterial3);
    const square3 = new THREE.Mesh(geoBuff, texMaterial3);
    square3.position.set(3, 2, 0);
    this.scene.add(square3);

    ///右下角正方形，纹理坐标会和tex.repeat叠加
    const tex4 = texLoader.load('./images/bg.jpg');
    this.texs.push(tex4);
    tex4.wrapS = THREE.RepeatWrapping;
    tex4.wrapT = THREE.RepeatWrapping;
    tex4.repeat.set(2, 2); // 设置纹理的重复

    const texMaterial4 = new THREE.MeshBasicMaterial({ map: tex4 });
    this.mats.push(texMaterial3);
    const square4 = new THREE.Mesh(geoBuff, texMaterial4);
    square4.position.set(3, -2, 0);
    this.scene.add(square4);

    const ambient = new THREE.AmbientLight(0xffffff, 0.2);
    this.scene.add(ambient);
    const dirLight = new THREE.DirectionalLight(0xffffff, 1);
    dirLight.position.set(0, 0, 5);
    dirLight.target.position.set(0, 0, 0);
    this.scene.add(dirLight);
    this.isRunning = true;
    const animate = (time) => {
      if (!this.isRunning || this.element === null) {
        return;
      }
      DebugInfo.Instance.begin();
      this.renderer.render(this.scene, this.camera);
      cube.rotation.x = 0.001 * time;
      cube.rotation.y = 0.001 * time;
      DebugInfo.Instance.end();
      requestAnimationFrame(animate);
    };
    animate(0);
  }

  onresize(e: UIEvent) {
    super.onresize(e);
    console.log('onresive');
    if (this.renderer) {
      this.renderer.setDrawingBufferSize(
        this.clientWidth,
        this.clientHeight,
        1
      );
      if (this.camera) {
        const aspect = this.clientHeight / this.clientWidth;
        this.camera.top = viewWidth * aspect;
        this.camera.bottom = -viewWidth * aspect;

        this.camera.updateProjectionMatrix();
      }
    }
  }

  destory() {
    this.texs.forEach((value) => {
      value.dispose();
    });
    this.geos.forEach((v) => {
      v.dispose();
    });
    this.mats.forEach((v) => {
      v.dispose();
    });
    this.geos = [];
    this.mats = [];
    this.texs = [];
    super.destory();
  }
}

export default new _5_01Texture();
